package invariant;

import com.alibaba.fastjson.JSONObject;
import framework.sepal4java.common.socket.CmdMessage;
import framework.sepal4java.common.struct.ResourceConfig;
import framework.sepal4java.common.util.Util;
import framework.sepal4java.lib4wrapper.WrapperRemoteConnector;
import service.ConfigNameEnum;
import service.ConfigService;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;

public class MockWrapper {

    private String FILE_PATH;

    {
        MockWrapper.class.getClassLoader().getResource("config/wrapper/data/");
    }

    private List<String> dataList;
    // 有无不变式的trace的数量
    private int TRACE_NUM = 30;

    // 表示当前时间
    private static long currentTime = 0;
    // 将一个时间范围内的映射到同一个数据中
    // 例如timeRange=100，那么0-99的时间映射到第一个数据，100-199的时间映射到第二个数据
    private static int timeRange = 100;


    private int currentTraceId = 0;

    public MockWrapper(boolean test, boolean withInv, int traceId){
//        MockWrapper.withInv = withInv;
//        generating = test;
        if(test){
            FILE_PATH = Objects.requireNonNull(MockWrapper.class.getClassLoader().getResource("config/wrapper/data/generate-" + traceId + ".txt")).getPath();
        }else if(withInv){
            FILE_PATH = Objects.requireNonNull(MockWrapper.class.getClassLoader().getResource("config/wrapper/data/with-inv-" + traceId + ".txt")).getPath();
        }else{
            FILE_PATH = Objects.requireNonNull(MockWrapper.class.getClassLoader().getResource("config/wrapper/data/without-inv-" + traceId + ".txt")).getPath();
        }
//        FILE_PATH = absPath + "/" + FILE_PATH;
    }

//    public void


    public void run() {
        // 这里MockCar的传感器包括了front、left和right
        ResourceConfig config = ResourceConfig.fromString(Util.readFileContent(ConfigService.getConfig(ConfigNameEnum.MOCK_CAR_JSON.getName())));
        WrapperRemoteConnector connector = WrapperRemoteConnector.getInstance();
        this.currentTraceId ++;
        try {
            dataList = Files.lines(Paths.get(FILE_PATH)).toList();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        if (connector.register("127.0.0.1", 9091, config)) {
            currentTime = System.currentTimeMillis();
            boolean dataEnd = false;
            while (!dataEnd) {
                CmdMessage msg = connector.recv();
                switch (msg.cmd) {
                    case "sensory_request":
                        String sensorData;
                        long timeInterval = System.currentTimeMillis() - currentTime;
                        int dataId = (int) (timeInterval / timeRange);
                        if (dataId < dataList.size()) {
                            sensorData = dataList.get(dataId);
                            String[] s = sensorData.split(" ");
                            JSONObject value = new JSONObject();
                            value.put("front", Integer.parseInt(s[0]));
                            value.put("left", Integer.parseInt(s[1]));
                            value.put("right", Integer.parseInt(s[2]));
                            CmdMessage response = new CmdMessage("sensory_back", value.toJSONString());
                            connector.send(response);
                            System.out.println("[Wrapper]: " + response);
                        }else{
                            System.out.println("No more data");
                            dataEnd = true;
                            break;
                        }
                        break;
                    case "data_lines":
                        dataEnd = true;
                        JSONObject data = new JSONObject();
                        data.put("dataLength", dataList.size());
                        CmdMessage dataResponse = new CmdMessage("data_lines_back", data.toJSONString());
                        connector.send(dataResponse);
                        System.out.println("[Wrapper]: " + dataResponse);
                        break;
                }
            }
            connector.close();
        }
    }

    public static void main(String[] args) {
        // 1-30指定读取的trace
        boolean withInv = "true".equalsIgnoreCase(args[1]);
        int traceId = Integer.parseInt(args[0]);
//        String absPath = args[2];
        MockWrapper mockWrapper = new MockWrapper(false, withInv, traceId);
        mockWrapper.run();
    }
}